home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1993-09-24 | 12.9 KB | 571 lines |
- IMPLEMENTATION MODULE cstr;
- __IMP_SWITCHES__
- #ifdef HM2
- #ifdef __LONG_WHOLE__
- (*$!i+: Modul muss mit $i- uebersetzt werden! *)
- (*$!w+: Modul muss mit $w- uebersetzt werden! *)
- #else
- (*$!i-: Modul muss mit $i+ uebersetzt werden! *)
- (*$!w-: Modul muss mit $w+ uebersetzt werden! *)
- #endif
- #endif
- (*****************************************************************************)
- (* 18-Sep-93, Holger Kleinschmidt *)
- (*****************************************************************************)
-
- VAL_INTRINSIC
- CAST_IMPORT
-
- FROM SYSTEM IMPORT
- (* PROC *) ADR;
-
- FROM PORTAB IMPORT
- (* CONST*) NULL,
- (* TYPE *) UNSIGNEDWORD, SIGNEDWORD;
-
- IMPORT e;
-
- FROM types IMPORT
- (* CONST*) EOS,
- (* TYPE *) sizeT, StrPtr, StrRange;
-
- (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
-
- VAR
- null : CHAR;
- nullP : StrPtr;
-
- (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
-
- PROCEDURE strlen ((* EIN/ -- *) strC : StrPtr ): sizeT;
- (*T*)
- VAR __REG__ len : StrRange;
- __REG__ ptr : StrPtr;
-
- BEGIN
- ptr := strC;
- IF ptr = NULL THEN
- RETURN(0);
- END;
- len := 0;
- WHILE ptr^[len] <> 0C DO
- INC(len);
- END;
- RETURN(VAL(sizeT,len));
- END strlen;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE strcpy ((* EIN/ -- *) dst : StrPtr;
- (* EIN/ -- *) src : StrPtr );
- (*T*)
- VAR __REG__ idx : StrRange;
- __REG__ c : CHAR;
- __REG__ d : StrPtr;
- __REG__ s : StrPtr;
-
- BEGIN
- d := dst;
- s := src;
- IF d = NULL THEN
- RETURN;
- ELSIF s = NULL THEN
- s := nullP;
- END;
- idx := 0;
- REPEAT
- c := s^[idx];
- d^[idx] := c;
- INC(idx);
- UNTIL c = 0C;
- END strcpy;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE strncpy ((* EIN/ -- *) dst : StrPtr;
- (* EIN/ -- *) src : StrPtr;
- (* EIN/ -- *) len : sizeT );
- (*T*)
- VAR __REG__ idx : StrRange;
- __REG__ c : CHAR;
- __REG__ d : StrPtr;
- __REG__ s : StrPtr;
- __REG__ l : StrRange;
-
- BEGIN
- d := dst;
- s := src;
- l := VAL(StrRange,len);
- IF (d = NULL) OR (l = 0) THEN
- RETURN;
- ELSIF s = NULL THEN
- s := nullP;
- END;
- idx := 0;
- REPEAT
- c := s^[idx];
- d^[idx] := c;
- INC(idx);
- DEC(l);
- UNTIL (c = 0C) OR (l = 0);
- WHILE l > 0 DO
- d^[idx] := 0C;
- INC(idx);
- DEC(l);
- END;
- END strncpy;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE strcat ((* EIN/ -- *) dst : StrPtr;
- (* EIN/ -- *) src : StrPtr );
- (*T*)
- VAR __REG__ dIdx : StrRange;
- __REG__ sIdx : StrRange;
- __REG__ c : CHAR;
- __REG__ d : StrPtr;
- __REG__ s : StrPtr;
-
- BEGIN
- d := dst;
- s := src;
- IF (d = NULL) OR (s = NULL) THEN
- RETURN;
- END;
- dIdx := 0;
- WHILE d^[dIdx] <> 0C DO
- INC(dIdx);
- END;
- sIdx := 0;
- REPEAT
- c := s^[sIdx];
- d^[dIdx] := c;
- INC(sIdx);
- INC(dIdx);
- UNTIL c = 0C;
- END strcat;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE strncat ((* EIN/ -- *) dst : StrPtr;
- (* EIN/ -- *) src : StrPtr;
- (* EIN/ -- *) len : sizeT );
- (*T*)
- VAR __REG__ dIdx : StrRange;
- __REG__ sIdx : StrRange;
- __REG__ c : CHAR;
- __REG__ d : StrPtr;
- __REG__ s : StrPtr;
- __REG__ l : StrRange;
-
- BEGIN
- d := dst;
- s := src;
- l := VAL(StrRange,len);
- IF (d = NULL) OR (s = NULL) OR (l = 0) THEN
- RETURN;
- END;
- dIdx := 0;
- WHILE d^[dIdx] <> 0C DO
- INC(dIdx);
- END;
- sIdx := 0;
- REPEAT
- c := s^[sIdx];
- d^[dIdx] := c;
- INC(sIdx);
- INC(dIdx);
- DEC(l);
- UNTIL (c = 0C) OR (l = 0);
- IF c <> 0C THEN
- d^[dIdx] := 0C;
- END;
- END strncat;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE strcmp ((* EIN/ -- *) str1 : StrPtr;
- (* EIN/ -- *) str2 : StrPtr ): INTEGER;
- (*T*)
- VAR __REG__ idx : StrRange;
- __REG__ c : CHAR;
- __REG__ s1 : StrPtr;
- __REG__ s2 : StrPtr;
-
- BEGIN
- s1 := str1;
- s2 := str2;
- IF s1 = NULL THEN
- IF s2 = NULL THEN
- RETURN(0);
- ELSE
- RETURN(-1);
- END;
- ELSIF s2 = NULL THEN
- RETURN(1);
- END;
-
- idx := 0;
- LOOP
- c := s1^[idx];
- IF c <> s2^[idx] THEN
- IF c < s2^[idx] THEN
- RETURN(-1);
- ELSE
- RETURN(1);
- END;
- ELSIF c = 0C THEN
- RETURN(0);
- END;
- INC(idx);
- END;
- END strcmp;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE strncmp ((* EIN/ -- *) str1 : StrPtr;
- (* EIN/ -- *) str2 : StrPtr;
- (* EIN/ -- *) len : sizeT ): INTEGER;
- (*T*)
- VAR __REG__ idx : StrRange;
- __REG__ c : CHAR;
- __REG__ s1 : StrPtr;
- __REG__ s2 : StrPtr;
- __REG__ l : StrRange;
-
- BEGIN
- s1 := str1;
- s2 := str2;
- l := VAL(StrRange,len);
- IF s1 = NULL THEN
- IF s2 = NULL THEN
- RETURN(0);
- ELSE
- RETURN(-1);
- END;
- ELSIF s2 = NULL THEN
- RETURN(1);
- END;
- IF l = 0 THEN
- RETURN(0);
- END;
-
- idx := 0;
- REPEAT
- c := s1^[idx];
- IF c <> s2^[idx] THEN
- IF c < s2^[idx] THEN
- RETURN(-1);
- ELSE
- RETURN(1);
- END;
- ELSIF c = 0C THEN
- RETURN(0);
- END;
- INC(idx);
- DEC(l);
- UNTIL l = 0;
- RETURN(0);
- END strncmp;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE strchr ((* EIN/ -- *) s : StrPtr;
- (* EIN/ -- *) c : CHAR ): StrPtr;
- (*T*)
- VAR __REG__ idx : StrRange;
- __REG__ ptr : StrPtr;
- __REG__ ch : CHAR;
-
- BEGIN
- ptr := s;
- IF ptr = NULL THEN
- RETURN(NULL);
- END;
- idx := 0;
- LOOP
- ch := ptr^[idx];
- IF ch = c THEN
- RETURN(CAST(StrPtr,ADR(ptr^[idx])));
- ELSIF ch = 0C THEN
- RETURN(NULL);
- END;
- INC(idx);
- END;
- END strchr;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE strrchr ((* EIN/ -- *) s : StrPtr;
- (* EIN/ -- *) c : CHAR ): StrPtr;
- (*T*)
- VAR __REG__ idx : StrRange;
- __REG__ ptr : StrPtr;
- __REG__ tmp : SIGNEDWORD;
- __REG__ ch : CHAR;
-
- BEGIN
- ptr := s;
- IF ptr = NULL THEN
- RETURN(NULL);
- END;
- tmp := -1;
- idx := 0;
- LOOP
- ch := ptr^[idx];
- IF ch = 0C THEN
- IF c = 0C THEN
- RETURN(CAST(StrPtr,ADR(ptr^[idx])));
- ELSIF tmp = -1 THEN
- RETURN(NULL);
- ELSE
- RETURN(CAST(StrPtr,ADR(ptr^[tmp])));
- END;
- END;
- IF ch = c THEN
- tmp := VAL(SIGNEDWORD,idx);
- END;
- INC(idx);
- END;
- END strrchr;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE strstr ((* EIN/ -- *) str : StrPtr;
- (* EIN/ -- *) pat : StrPtr ): StrPtr;
- (*T*)
- VAR __REG__ pLen : StrRange;
- __REG__ sLen : StrRange;
- __REG__ pIdx : StrRange;
- __REG__ sIdx : StrRange;
- __REG__ s : StrPtr;
- __REG__ p : StrPtr;
-
- BEGIN
- s := str;
- p := pat;
- IF (s = NULL) OR (p = NULL) THEN
- RETURN(NULL);
- END;
- pLen := 0;
- WHILE p^[pLen] <> 0C DO
- INC(pLen);
- END;
- sLen := 0;
- WHILE s^[sLen] <> 0C DO
- INC(sLen);
- END;
- IF pLen = 0 THEN
- RETURN(CAST(StrPtr,ADR(s^[sLen])));
- ELSIF pLen > sLen THEN
- RETURN(NULL);
- END;
-
- DEC(sLen, pLen);
- sIdx := 0;
- LOOP
- pIdx := 0;
- WHILE (pIdx < pLen) AND (s^[sIdx] = p^[pIdx]) DO
- INC(sIdx);
- INC(pIdx);
- END;
- DEC(sIdx, pIdx);
-
- IF pIdx = pLen THEN
- RETURN(CAST(StrPtr,ADR(s^[sIdx])));
- ELSIF sLen = 0 THEN
- RETURN(NULL);
- END;
-
- INC(sIdx);
- DEC(sLen);
- END;
- END strstr;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE strpbrk ((* EIN/ -- *) str : StrPtr;
- (* EIN/ -- *) brk : StrPtr ): StrPtr;
- (*T*)
- VAR __REG__ bIdx : StrRange;
- __REG__ bLen : StrRange;
- __REG__ sIdx : StrRange;
- __REG__ c : CHAR;
- __REG__ b : StrPtr;
- __REG__ s : StrPtr;
-
- BEGIN
- s := str;
- b := brk;
- IF (s = NULL) OR (b = NULL) THEN
- RETURN(NULL);
- END;
- bLen := VAL(StrRange,strlen(b));
- sIdx := 0;
- WHILE s^[sIdx] <> 0C DO
- c := s^[sIdx];
- bIdx := 0;
- WHILE (bIdx < bLen) AND (b^[bIdx] <> c) DO
- INC(bIdx);
- END;
- IF bIdx < bLen THEN
- RETURN(CAST(StrPtr,ADR(s^[sIdx])));
- END;
- INC(sIdx);
- END;
- RETURN(NULL);
- END strpbrk;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE strerror ((* EIN/ -- *) errnum : INTEGER;
- (* -- /AUS *) VAR errstr : ARRAY OF CHAR );
- (*T*)
- VAR text : ARRAY [0..40] OF CHAR;
- sIdx : UNSIGNEDWORD;
- dIdx : UNSIGNEDWORD;
-
- BEGIN
- CASE errnum OF
- e.eOK : text := "OK";
- |e.eRROR : text := "error";
- |e.eDRVNR : text := "device not ready";
- |e.eUNCMD : text := "unknown command";
- |e.eCRC : text := "crc error";
- |e.eBADRQ : text := "bad request";
- |e.eSEEK : text := "seek error";
- |e.eMEDIA : text := "unknown media";
- |e.eSECNF : text := "sector not found";
- |e.ePAPER : text := "out of paper";
- |e.eWRITF : text := "write failure";
- |e.eREADF : text := "read failure";
- |e.eGENRL : text := "general error";
- |e.eWRPRO : text := "write protected";
- |e.eCHNG : text := "media changed";
- |e.eUNDEV : text := "unknown device";
- |e.eBADSF : text := "bad sectors found";
- |e.eOTHER : text := "another disk";
-
- |e.eINSERT : text := "insert media";
- |e.eDVNRSP : text := "device not responding";
-
- |e.eINVFN : text := "invalid function number";
- |e.eFILNF : text := "file not found";
- |e.ePTHNF : text := "path not found";
- |e.eNHNDL : text := "no more handles";
- |e.eACCDN : text := "access denied";
- |e.eIHNDL : text := "invalid handle";
- |e.eNSMEM : text := "out of memory";
- |e.eIMBA : text := "invalid memory block";
- |e.eDRIVE : text := "invalid drive";
- |e.eNSAME : text := "different drives";
- |e.eNMFIL : text := "no more files";
-
- |e.eLOCKED : text := "file locked";
- |e.eNSLOCK : text := "invalid lock";
-
- |e.eRANGE : text := "range error";
- |e.eINTRN : text := "internal error";
- |e.ePLFMT : text := "not executable";
- |e.eGSBF : text := "memory block growth failure";
-
- |e.E2BIG : text := "argument list too long";
- |e.EAGAIN : text := "try again";
- |e.EBUSY : text := "resource unavailable";
- |e.EDEADLK : text := "deadlock would result";
- |e.EDOM : text := "domain error";
- |e.EEXIST : text := "file exists";
- |e.EFBIG : text := "file too large";
- |e.EINTR : text := "interrupted by signal";
- |e.EINVAL : text := "invalid argument";
- |e.EISDIR : text := "is a directory";
- |e.EMLINK : text := "too many links";
- |e.ENAMETOOLONG : text := "filename too long";
- |e.ENOLCK : text := "no locks available";
- |e.ENOSPC : text := "no space left on device";
- |e.ENOTEMPTY : text := "directory not empty";
- |e.ENOTTY : text := "wrong i/o control op";
- |e.EPIPE : text := "broken pipe";
- |e.ERANGE : text := "result too large";
- |e.ESPIPE : text := "invalid seek";
- |e.ELOOP : text := "too many symbolic links";
- ELSE
- text := "unknown error";
- END;
- dIdx := 0;
- sIdx := 0;
- WHILE (dIdx <= VAL(UNSIGNEDWORD,HIGH(errstr))) AND (text[sIdx] <> EOS) DO
- errstr[dIdx] := text[sIdx];
- INC(dIdx);
- INC(sIdx);
- END;
- IF dIdx <= VAL(UNSIGNEDWORD,HIGH(errstr)) THEN
- errstr[dIdx] := EOS;
- END;
- END strerror;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE AssignM2ToC ((* EIN/ -- *) REF strM2 : ARRAY OF CHAR;
- (* EIN/ -- *) sizeC : StrRange;
- (* EIN/ -- *) strC : StrPtr );
- (*T*)
- VAR __REG__ idx : StrRange;
- __REG__ max : StrRange;
- __REG__ ptr : StrPtr;
-
- BEGIN
- ptr := strC;
- IF (ptr = NULL) OR (sizeC = 0) THEN
- RETURN;
- END;
-
- IF VAL(StrRange,HIGH(strM2)) < sizeC THEN
- max := VAL(StrRange,HIGH(strM2));
- ELSE
- max := sizeC - 1;
- END;
- idx := 0;
- WHILE (idx <= max) AND (strM2[idx] <> EOS) DO
- ptr^[idx] := strM2[idx];
- INC(idx);
- END;
- IF idx < sizeC THEN
- ptr^[idx] := 0C;
- END;
- END AssignM2ToC;
-
- (*---------------------------------------------------------------------------*)
-
- PROCEDURE AssignCToM2 ((* EIN/ -- *) strC : StrPtr;
- (* -- /AUS *) VAR strM2 : ARRAY OF CHAR );
- (*T*)
- VAR __REG__ idx : StrRange;
- __REG__ c : CHAR;
- __REG__ ptr : StrPtr;
-
- BEGIN
- ptr := strC;
- IF ptr = NULL THEN
- strM2[0] := EOS;
- RETURN;
- END;
- idx := 0;
- c := ptr^[0];
- WHILE (idx <= VAL(StrRange,HIGH(strM2))) AND (c <> 0C) DO
- strM2[idx] := c;
- INC(idx);
- c := ptr^[idx];
- END;
- IF idx <= VAL(StrRange,HIGH(strM2)) THEN
- strM2[idx] := EOS;
- END;
- END AssignCToM2;
-
- (*===========================================================================*)
-
- BEGIN (* cstr *)
- null := 0C;
- nullP := CAST(StrPtr,ADR(null));
- END cstr.
-